/**
 * @file /src/main_window.cpp
 *
 * @brief Implementation for the qt gui.
 *
 * @date October 2025
 **/
/*****************************************************************************
** Includes
*****************************************************************************/

#include <QtGui>
#include "rclcpp/rclcpp.hpp"
#include <QMessageBox>
#include <iostream>
#include <QObject>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>

#include "main_window.hpp"
#include "add_cmd_dialog.hpp"

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace rhzd_assist {

using namespace Qt;

/*****************************************************************************
** Implementation [MainWindow]
*****************************************************************************/

MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
    : QMainWindow(parent), qnode(argc,argv)
{
    ui.setupUi(this);
    // setFocusPolicy(Qt::StrongFocus);
    _cmd = new QProcess;
    _cmd->start("bash", QStringList());
    //connect
    QObject::connect(ui.mn_addcmd, SIGNAL(QAction::triggered()), this, SLOT(on_mn_addcmd_triggered));
    QObject::connect(ui.cb_open_image, SIGNAL(clicked()), this, SLOT(on_cb_open_image_clicked(bool)));
    QObject::connect(ui.rb_image_raw, SIGNAL(toggled()), this, SLOT(on_rb_image_raw_toggled(bool)));
    QObject::connect(ui.rb_image_depth, SIGNAL(toggled()), this, SLOT(on_rb_image_depth_toggled(bool)));
    QObject::connect(&qnode, SIGNAL(batteryState(double)), this, SLOT(slot_battery_state(double)));
    connect(&qnode, SIGNAL(image_val(QImage)), this,SLOT(updata_image(QImage)));
    qnode.init();
    QString config_file_path;
    qnode.get_config_directory(config_file_path);
    std::cout << "config file path: " << config_file_path.toStdString() << std::endl;
    buttons_cfg_file_path = config_file_path + "/buttons.json";
    load_dynamic_buttons();
    std::cout << "main window start..." << std::endl;
}

MainWindow::~MainWindow()
{
    // QProcess::execute("killall -s INT -w ros2\n");
    QProcess::execute("killall", QStringList() << "-s" << "INT" << "-w" << "ros2");
    std::cout << "main window end..." << std::endl;
}

void rhzd_assist::MainWindow::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
    qDebug() << "MainWindow::closeEvent()";
    save_dynamic_buttons();
}

void rhzd_assist::MainWindow::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape) {
        if (isFullScreen()) {
            qDebug() << "MainWindow::keyPressEvent() - Qt::Key_Escape showNormal";
            showNormal();
        }
    } else if (event->key() == Qt::Key_F11) {
        if (isFullScreen()) {
            qDebug() << "MainWindow::keyPressEvent() - Qt::Key_F11 showNormal";
            showNormal();
        } else {
            qDebug() << "MainWindow::keyPressEvent() - Qt::Key_F11 showFullScreen";
            showFullScreen();
        }
    }
    QWidget::keyPressEvent(event);
}

/*****************************************************************************
** Implementation [Slots]
*****************************************************************************/

// 电量显示
void rhzd_assist::MainWindow::slot_battery_state(double msg)
{
    if (battery_voltage == msg) {
        return;
    }
    battery_voltage = msg;

    qDebug() << "battery voltage: " << battery_voltage << "V";
    if(battery_voltage > 25) ui.progressBarBattery->setValue(100);
    else if(battery_voltage >= 20) ui.progressBarBattery->setValue((1-(25-battery_voltage)/5)*100);
    else ui.progressBarBattery->setValue(0);
    // if(ui.progressBarBattery->value()<=30)ui.label_4->setPixmap(QPixmap::fromImage(QImage("://images/power-l.png")));
    // else if(ui.progressBarBattery->value()>30)ui.label_4->setPixmap(QPixmap::fromImage(QImage("://images/power-v.png")));
}

void rhzd_assist::MainWindow::on_mn_addcmd_triggered(void)
{
    AddCmdDiaglog dialog(this);

    qDebug() << "add command";
    if(dialog.exec() == QDialog::Accepted) {
        QString buttonName = dialog.getButtonName();
        QString command = dialog.getCommand();

        qDebug() << "name: " << buttonName;
        qDebug() << "cmd: " << command;
        add_dynamic_button(buttonName, command);

        QMessageBox::information(this, "成功",
            QString("命令已保存！\n按键名: %1\n命令: %2").arg(buttonName).arg(command));
    }
}

void rhzd_assist::MainWindow::on_cb_open_image_clicked(bool checked)
{
    qDebug() << "button clicked : " << checked;
    if (!checked) {
        QPixmap pixmap(":resources/images/qiyuanxindongli.jpg");
        // ui.label_img->setPixmap(pixmap.scaled(ui.label_img->size()));
        ui.label_img->setPixmap(pixmap);
    }
    qnode.set_image_preview(checked);
}

void rhzd_assist::MainWindow::on_rb_image_raw_toggled(bool toggled)
{
    qDebug() << "rb image raw button toggled : " << toggled;
    if (toggled) {
        qnode.set_image_preview(ImgPreviewType::RAW);
    }
}

void rhzd_assist::MainWindow::on_rb_image_depth_toggled(bool toggled)
{
    qDebug() << "rb image depth button toggled : " << toggled;
    if (toggled) {
        qnode.set_image_preview(ImgPreviewType::DETPH);
    }
}

void rhzd_assist::MainWindow::on_dbutton_delete(DynamicButton *button)
{
    qDebug() << "dynamic button deleted: " << button->text();
    button_list.removeOne(button);
}

//图像显示
void rhzd_assist::MainWindow::updata_image(QImage im)
{
    if (!ui.cb_open_image->isChecked()) {
        return;
    }
    auto size = ui.label_img->size();
    auto max_size = ui.label_img->maximumSize();
    if ((size.width() < max_size.width()) && (size.height() < max_size.height())) {
        size *= 2;
    }
    // ui.label_img->setPixmap(QPixmap::fromImage(im).scaled(ui.label_img->width(), ui.label_img->height()));
    // ui.label_img->setPixmap(QPixmap::fromImage(im).scaled(ui.label_img->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    ui.label_img->setPixmap(QPixmap::fromImage(im).scaled(size, Qt::IgnoreAspectRatio));
}

void rhzd_assist::MainWindow::load_dynamic_buttons(void)
{
    QFile file(buttons_cfg_file_path);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Error: Cannot open file";
        return;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(data, &error);

    if (error.error != QJsonParseError::NoError) {
        qDebug() << "Error: Cannot parse JSON";
        return;
    }

    if (!doc.isArray()) {
        qDebug() << "Error: JSON is not an array";
        return;
    }

    QJsonArray buttonArray = doc.array();

    for (const QJsonValue &value : buttonArray) {
        if (value.isObject()) {
            QJsonObject buttonObj = value.toObject();
            QString name = buttonObj["name"].toString();
            QString action = buttonObj["action"].toString();
            qDebug() << "find object: " << name;
            add_dynamic_button(name, action);
        }
    }
}

void MainWindow::save_dynamic_buttons(void)
{
    QJsonArray buttonArray;

    for (DynamicButton *button : button_list) {
        qDebug() << "save dynamic button: " << button->text();
        QString name = button->text();
        QString action = button->getCmd();
        buttonArray.append(create_button_object(name, action));
    }

    QJsonDocument doc(buttonArray);
    QFile file(buttons_cfg_file_path);

    if (file.open(QIODevice::WriteOnly)) {
        file.write(doc.toJson());
        file.close();
        qDebug() << "save dynamic buttons to json file: " << buttons_cfg_file_path;
    } else {
        qDebug() << "failed to save dynamic buttons to json file: " << buttons_cfg_file_path;
    }
}

QJsonObject MainWindow::create_button_object(const QString &name, const QString &action)
{
    QJsonObject buttonObj;
    buttonObj["name"] = name;
    buttonObj["action"] = action;
    qDebug() << "buttonObj: " << buttonObj;
    return buttonObj;
}

void rhzd_assist::MainWindow::add_dynamic_button(QString button_name, QString action)
{
    DynamicButton *button = new DynamicButton(button_name, this);
    qDebug() << "button name: " << button_name;
    qDebug() << "button action: " << action;
    button->setCmd(action);
    connect(button, &DynamicButton::sigDbuttonDelete, this, &MainWindow::on_dbutton_delete);
    connect(button, &DynamicButton::clicked, this, [=]() {
        qDebug() << "button clicked: " << button->text();
        QString cmd = button->getCmd();
        qDebug() << "cmd: " << cmd;
        if (!cmd.isEmpty()) {
            _cmd->write((cmd + "\n").toStdString().c_str());
            // _cmd->write(cmd.toStdString().c_str());
        }
    });

    int count = ui.sawc_vlayout->count();
    int index = count-1;

    if (index < 0)  {
        qDebug() << "something error";
        return;
    }

    ui.sawc_vlayout->insertWidget(index, button, Qt::AlignLeft | Qt::AlignTop);
    ui.sa_dynamic_widget->ensureWidgetVisible(button);
    ui.sawc_vlayout->update();
    button_list.append(button);
}

}

